package com.csii.adhoc.controller.dataReady;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.csii.adhoc.annotation.OperationLog;
import com.csii.adhoc.dataready.*;
import com.csii.adhoc.dataready.service.*;
import com.csii.adhoc.dataunits.service.DataUnitsService;
import com.csii.adhoc.dblink.DbLinkPo;
import com.csii.adhoc.dblink.DbLinkVo;
import com.csii.adhoc.exception.ParamValidityException;
import com.csii.adhoc.id.UidGenerator;
import com.csii.adhoc.util.DateUtils;
import com.csii.common.DbLinkUtils;
import com.csii.result.APIResult;
import com.csii.result.PageVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

import com.csii.adhoc.dblink.service.DbLinkService;

/**
 * @description: 数据准备
 * @author: zyliu
 * @create: 2021-01-13 19:53
 */
@RestController
@Slf4j
    @RequestMapping("/datasetOper")
public class DatasetQueryController {
    @Autowired
    private DatasetQueryService datasetQueryService;
    @Autowired
    private TDataTaskService tDataTaskService;
    @Autowired
    DbLinkService dbLinkService;
    @Autowired
    TDataFldService tDataFldService;
    @Autowired
    TDataFromService tDataFromService;
    @Autowired
    TDataRelationService tDataRelationService;
    @Autowired
    TDataRelationDtlService tDataRelationDtlService;
    @Autowired
    TDataMergeService tDataMergeService;
    @Autowired
    TDataMergeDtlService tDataMergeDtlService;
    @Autowired
    TDataCondService tDataCondService;
    @Autowired
    TDataParamService tDataParamService;
    @Autowired
    DbLinkUtils dbLinkUtils;
    @Autowired
    UidGenerator uidGenerator;
    @Autowired
    DataUnitsService dataUnitsService;

    @OperationLog("数据集维护")
    @PostMapping("tDataTaskMaintain")
    public APIResult<?> tDataTaskMaintain(@RequestBody TDataTaskPo vo) {
        String userId = String.valueOf(SecurityUtils.getSubject().getPrincipal());
        vo.setUpdatedBy(userId)
                .setUpdatedDt(DateUtils.getDateString("yyyyMMddHHmmss"));
        tDataTaskService.tDataTaskMaintain(vo, vo.getOptMode());
        return APIResult.successResult(vo);
    }

    @OperationLog("关联视图明细查询")
    @PostMapping("tDataRelationDtlQuery")
    public APIResult<?> tDataRelationDtlQuery(@RequestBody TDataRelationPo vo) {
        List<TDataRelationPo> tDataRelationPos = datasetQueryService.tDataRelationDtlQuery(vo);
        return APIResult.successResult(tDataRelationPos);
    }

    @OperationLog("关联视图维护")
    @PostMapping("assoViewMaintain")
    public APIResult<?> assoViewMaintain(@RequestBody TDataRelationPo vo) {
        String userid = String.valueOf(SecurityUtils.getSubject().getPrincipal());
        vo.setUpdatedBy(userid)
                .setUpdatedDt(DateUtils.getDateString("yyyyMMddHHmmss"));
        TDataRelationPo tDataRelationPo = datasetQueryService.assoViewMaintain(vo);
        return APIResult.successResult(tDataRelationPo);
    }

    @OperationLog("关联明细字段维护")
    @PostMapping("tDataRelationDtlMaintain")
    public APIResult<?> tDataRelationDtlMaintain(@RequestBody TDataRelationDtlPo vo) {
        String userid = String.valueOf(SecurityUtils.getSubject().getPrincipal());
        vo.setUpdatedBy(userid)
                .setUpdatedDt(DateUtils.getDateString("yyyyMMddHHmmss"));
        if (!vo.getMFldType().equals(vo.getSFldType())) {
            log.error(_LINE_() + "关联明细数据类型不符！");
            throw new ParamValidityException("关联明细数据类型不符！");
        }
        switch (vo.getOptMode()) {
            case "A":
                tDataRelationDtlService.insertOneTDataRelationDtl(vo);
                break;
            case "D":
                tDataRelationDtlService.deleteTDataRelationDtlByPrimaryKey(vo.getRelationId(), vo.getMasterFld(), vo.getSlaveFld());
                break;
            case "U":
                tDataRelationDtlService.updateTDataRelationDtlByPrimaryKey(vo);
                break;
            default:
                log.error(_LINE_() + "无效的操作标志:" + vo.getOptMode());
                throw new ParamValidityException("无效的操作标志:" + vo.getOptMode());
        }

        return APIResult.successResult(vo);
    }


    @OperationLog("数据集左右合并明细查询")
    @PostMapping("tDataMergeDtlQuery")
    public APIResult<?> tDataMergeDtlQuery(@RequestBody TDataMergePo vo) {

        List<TDataMergePo> tdrps = datasetQueryService.tDataMergeDtlQuery(vo);
        return APIResult.successResult(tdrps);
    }

    @OperationLog("数据集左右合并维护")
    @PostMapping("tDataMergeMaintain")
    public APIResult<?> tDataMergeMaintain(@RequestBody TDataMergePo vo) {
        String userid = String.valueOf(SecurityUtils.getSubject().getPrincipal());
        vo.setUpdatedBy(userid)
                .setUpdatedDt(DateUtils.getDateString("yyyyMMddHHmmss"));
        TDataMergePo tDataMergePo = datasetQueryService.tDataMergeMaintain(vo);
        return APIResult.successResult(tDataMergePo);
    }

    @OperationLog("数据集左右合并明细字段维护")
    @PostMapping("tDataMergeDtlMaintain")
    @Transactional
    public APIResult<?> tDataMergeDtlMaintain(@RequestBody TDataMergeDtlPo vo) {

        if (!vo.getMFldType().equals(vo.getSFldType())) {
            log.error(_LINE_() + "左右合并明细数据类型不符！");
            throw new ParamValidityException("左右合并明细数据类型不符！");
        }
        switch (vo.getOptMode()) {
            case "A":
                tDataMergeDtlService.insertOneTDataMergeDtl(vo);
                break;
            case "D":
                tDataMergeDtlService.deleteTDataMergeDtlByPrimaryKey(vo.getRelationId(), vo.getMasterFld(), vo.getSlaveFld());
                break;
            case "U":
                tDataMergeDtlService.updateTDataMergeDtlByPrimaryKey(vo);
                break;
            default:
                log.error(_LINE_() + "无效的操作标志:" + vo.getOptMode());
                throw new ParamValidityException("无效的操作标志:" + vo.getOptMode());
        }

        return APIResult.successResult(vo);
    }

    @OperationLog("全字段查询")
    @PostMapping("allFieldQuery")
    public APIResult<?> allFieldQuery(@RequestBody TDataTaskPo vo) {
        List<Map<String, Object>> list;
        list = datasetQueryService.allFieldQuery(vo);
        return APIResult.successResult(list);
    }


    @PostMapping("tDataCondQuery")
    public APIResult<?> tDataCondQuery(@RequestBody TDataCondPo vo) {
        List<TDataCondPo> list = tDataCondService.selectListTDataCond(vo.getModelId());
        CondTreeBuilder tb = new CondTreeBuilder(list);
        JSONArray ja = tb.buildJSONTree();

        return APIResult.successResult(ja);
    }

    @OperationLog("已选择字段查询")
    @PostMapping("tDataFldQuery")
    public APIResult<?> tDataFldQuery(@RequestBody TDataFldPo vo) {
        List<TDataFldPo> list = tDataFldService.selectListTDataFld(vo.getModelId());
        list.forEach(x -> {//转驼峰命名
            String fldEnname = x.getFldEnname();
            x.setHumpName(StrUtil.toCamelCase(fldEnname.toLowerCase()));
        });
        return APIResult.successResult(list);
    }

    @OperationLog("业务数据库列表查询")
    @PostMapping("tableListQuery")
    public APIResult<?> tableListQuery(@RequestBody DbLinkVo vo) {
        DbLinkPo po = dbLinkService.selectDbLinkByPrimaryKey(vo.getConnId());
        if (po == null) {
            log.error(_LINE_() + "该连接id无记录，connId" + vo.getConnId());
            throw new ParamValidityException("该连接id无记录，connId" + vo.getConnId());
        }
        PageVo<Map<String, Object>> pageSqlResult = datasetQueryService.tableListQuery(vo);
        return APIResult.successResult(pageSqlResult);
    }

    @OperationLog("自定义sql维护")
    @PostMapping("custSqlMaintain")

    public APIResult<?> custSqlMaintain(@RequestBody TDataTaskPo vo) {
        TDataTaskPo tDataTaskPo = datasetQueryService.custSqlMaintain(vo);
        return APIResult.successResult(tDataTaskPo);
    }

    @OperationLog("自定义sql参数维护")
    @PostMapping("tDataParamMaintain")
    @Transactional
    public APIResult<?> tDataParamMaintain(@RequestBody TDataParamPo vo) {

        //维护sql参数列表
        switch (vo.getOptMode()) {
            case "A":
                tDataParamService.insertOneTDataParam(vo);
                break;
            case "U":
                tDataParamService.updateTDataParamByPrimaryKey(vo);
                break;
            case "D":
                tDataParamService.deleteBySeqno(vo.getModelId(), vo.getSeqno());
                break;
            default:
                log.error(_LINE_() + "操作标志出错，optMode:" + vo.getOptMode());
                throw new ParamValidityException("操作标志出错，optMode:" + vo.getOptMode());
        }

        return APIResult.successResult(vo);
    }

    @OperationLog("自定义数据表维护")
    @PostMapping("custTableMaintain")
    public APIResult<?> custTableMaintain(@RequestBody TDataTaskPo vo) {
        if ("A".equals(vo.getOptMode())
                && (vo.getTdfrs() == null || vo.getTdfrs().size() < 1)) {
            log.error(_LINE_() + "新增时至少需要一个主表");
            throw new ParamValidityException("新增时至少需要一个主表");
        }
        if (vo.getModelType() == null) {
            log.error(_LINE_() + "模型类型modelType不能为空");
            throw new ParamValidityException("模型类型modelType不能为空!");
        }
        //防止前端上传 目录查询时拼接的modelType,如"14"
        if (vo.getModelType().length() == 2) {
            vo.setModelType(vo.getModelType().substring(1, 2));
        }
        TDataTaskPo tDataTaskPo = datasetQueryService.custTableMaintain(vo);

        return APIResult.successResult(tDataTaskPo);
    }

    @OperationLog("自定义数据表已选择字段维护")
    @PostMapping("tDataFldMaintain")
    @Transactional
    public APIResult<?> tDataFldMaintain(@RequestBody TDataFldPo vo) {
        List<TDataFldPo> list = vo.getTdfds();

        switch (vo.getOptMode()) {
            case "A":
            case "U":
                for (TDataFldPo p : list) {
                    p.setModelId(vo.getModelId());
                }
                tDataFldService.deleteByModelId(vo.getModelId());
                tDataFldService.insertListTDataFld(vo.getTdfds());
                break;
            case "D":
                tDataFldService.deleteByModelId(vo.getModelId());
                break;
            default:
                log.error(_LINE_() + "操作标志出错，optMode:" + vo.getOptMode());
                throw new ParamValidityException("操作标志出错，optMode:" + vo.getOptMode());
        }

        return APIResult.successResult(vo);
    }

    @OperationLog("数据表临时查询")
    @PostMapping("tDataTempQuery")
    public APIResult<?> tDataTempQuery(@Validated @RequestBody TDataViewPo po) {
        PageVo<Map<String, Object>> mapPageVo = datasetQueryService.tDataTempQuery(po);
        return APIResult.successResult(mapPageVo);
    }

    // 当前行号
    public static int _LINE_() {
        StackTraceElement traceElement = ((new Exception()).getStackTrace())[1];
        return traceElement.getLineNumber();
    }

    @OperationLog("数据集查询")
    @PostMapping("tDataTaskQuery")
    public APIResult<?> tDataTaskQuery(@Validated @RequestBody TDataTaskPo po) {
        TDataTaskPo tDataTaskPo = datasetQueryService.tDataTaskQuery(po);
        return APIResult.successResult(tDataTaskPo);
    }

    /**
     * create by: zyliu
     * description: 查询SQL模型参数列表
     * create time: 2021/2/16 23:09
     */
    @OperationLog("SQL模型参数查询")
    @PostMapping("tDataParamQuery")
    public APIResult<?> tDataParamQuery(@RequestBody TDataParamPo po) {
        if (po.getModelId() == null) {
            log.error(_LINE_() + "模型ID不能为空,modelId:" + po.getModelId());
            throw new ParamValidityException("模型ID不能为空,modelId:" + po.getModelId());
        }
        List<TDataParamPo> list = tDataParamService.selectListTDataParam(po.getModelId());
        return APIResult.successResult(list);
    }

    /**
     * create by: hd
     * description: 保存当前对象的别名
     * create time: 2024/1/31 21:09
     */
    @OperationLog("SQL模型别名查询")
    @PostMapping("saveNickName")
    public APIResult<?> saveNickName(@RequestBody TDataNickName po) {
        if (po.getModelId() == null) {
            log.error(_LINE_() + "模型ID不能为空,modelId:" + po.getModelId());
            throw new ParamValidityException("模型ID不能为空,modelId:" + po.getModelId());
        }
        tDataParamService.saveNickName(po);
        return APIResult.successResult("保存别名成功！");
    }

    @OperationLog("SQL模型参数查询")
    @PostMapping("queryExistNickName")
    public APIResult<?> queryExistNickName(@RequestBody TDataNickName po) {
        if (po.getModelId() == null) {
            log.error(_LINE_() + "模型ID不能为空,modelId:" + po.getModelId());
            throw new ParamValidityException("模型ID不能为空,modelId:" + po.getModelId());
        }
        List<TDataNickName> list = tDataParamService.queryExistNickName(po);
        return APIResult.successResult(list);
    }


    @OperationLog("SQL模型参数查询")
    @PostMapping("updateNickNameInfo")
    public APIResult<?> updateNickNameInfo(@RequestBody TDataNickName po) {
        if (po.getModelId() == null) {
            log.error(_LINE_() + "模型ID不能为空,modelId:" + po.getModelId());
            throw new ParamValidityException("模型ID不能为空,modelId:" + po.getModelId());
        }
        tDataParamService.updateNickNameInfo(po);
        return APIResult.successResult("修改成功！");
    }

}
